<template>
  <el-row>
    <el-alert type="info" show-icon>
      <template #title>
        <el-text size="small">当前展示的物模型是已发布到线上的版本 {{ versionTip }}，如需修改，请点击</el-text>
        <el-text size="small" type="primary" class="cursor" @click="viewDraft">编辑草稿</el-text>
      </template>
    </el-alert>
  </el-row>
  <el-row>
    <el-button type="primary" icon="el-icon-pointer" @click="viewDraft">前往编辑草稿</el-button>
    <el-tooltip
      class="item"
      effect="dark"
      content="查看物模型的 TSL(Thing Specification Language) 描述语言"
      placement="top"
    >
      <el-button @click="openTsl">物模型 TSL</el-button>
    </el-tooltip>
    <el-tooltip
      class="item"
      effect="dark"
      content="将JSON格式的物模型配置读取并导出"
      placement="top"
    >
      <el-button @click="exportTsl">物模型 导出</el-button>
    </el-tooltip>
<!--    <el-button>配置时序存储</el-button>-->
  </el-row>
  <el-row>
    <el-col :span="3">
      <avue-tree ref="tree"
                 :option="optionTree"
                 :data="dataTree"
                 v-model="formTree"
                 :filter-node-method="filterNodeMethod"
                 @node-click="nodeClickTree">
        <template #default="{ node, data }">
              <span class="custom-tree-node">
                <span v-if="data.isDefault === 1">默认模块</span>
                <span v-else>{{ node.label }}</span>
              </span>
        </template>
      </avue-tree>
    </el-col>
    <el-col :span="1">
      <el-dialog v-model="visibleTsl" :before-close="beforeCloseTsl" title="物模型" width="600">
        <el-row>
          <el-alert
              title="物模型是云端对设备功能的抽象描述，涵盖了设备的属性、服务和事件。物联网平台通过物的描述语言，即 TSL（Thing Specification Language），以 JSON 格式表达这一模型。开发者可以利用 TSL 构建并上报设备数据。完整的物模型可用于云端应用的开发，而精简版的物模型则可结合设备端SDK用于设备的开发工作。"
              type="info" :closable="false"/>
        </el-row>
        <el-row>
          <el-select
              v-model="blockId"
              clearable
              placeholder="请选择模块"
              @change="blockTslChange"
              style="width: 240px"
          >
            <el-option
                v-for="item in dataTree"
                :key="item.value"
                :label="item.isDefault === 1 ? '默认模块': item.title"
                :value="item.value"
            />
          </el-select>
        </el-row>
        <el-row>
          <code-editor v-model="tsl" :json="true" :readonly="true" theme="nord"/>
        </el-row>
      </el-dialog>
    </el-col>
    <el-col :span="20">
      <avue-crud ref="crud"
                 :option="option"
                 :data="data"
                 v-model="form"
                 :table-loading="loading"
                 :before-open="beforeOpen"
                 :before-close="beforeClose"
                 @on-load="onLoad">
        <template #menu-left>
          <el-text size="large">{{ activeName }}</el-text>
        </template>
        <template #functionType="{ row }">
          <el-tag style="cursor: pointer">{{ row.functionTypeName }}</el-tag>
        </template>
        <template #specEnum-form="{}">
          <function-enum v-model="enumsData" :snapshot-mode="snapshotMode"></function-enum>
        </template>
        <template #specStruct-form="{}">
          <function-struct v-model="structData" :snapshot-mode="snapshotMode"></function-struct>
        </template>
        <template #specInput-form="{}">
          <function-struct-full v-model="inputData" :snapshot-mode="snapshotMode"></function-struct-full>
        </template>
        <template #specOutput-form="{}">
          <function-struct-full v-model="outputData" :snapshot-mode="snapshotMode"></function-struct-full>
        </template>
      </avue-crud>
    </el-col>
  </el-row>
</template>

<script>
import {validatenull} from "@/utils/validate";
import {
  option,
  optionTree,
  fieldTypeName,
  dataTypeName,
} from "@/option/iot/function";
import { getDetail } from '@/api/iot/product';
import { dataPublishedByKey, dataPublishedTsl } from "@/api/iot/product/version";
import func from "@/utils/func";
import { exportBlob } from '@/api/common';
import { downloadJson } from '@/utils/util';

export default {
  name: 'productFunction',
  props: {
    productKey: String,
    productId: String,
  },
  data() {
    return {
      activeName: '默认模块',
      blockId: '',
      form: {},
      tsl: "",
      detail: {},
      query: {},
      search: {},
      loading: false,
      visible: false,
      visibleTsl: false,
      versionId: "",
      versionTip: "",
      versionSelect: [],
      snapshotMode: true,
      option: option(this),
      optionTree: optionTree,
      formBlock: {},
      formTree: {},
      formVersion: "",
      data: [],
      dataTree: [],
      structData: [],
      enumsData: [],
      inputData: [],
      outputData: [],
      dataSnapshot: {},
      functionSnapshot: [],
      blockSnapshot: [],
    };
  },
  mounted() {
    this.snapshotOperation();
  },
  created() {
    this.init();
  },
  watch: {
    productId() {
      if (!validatenull(this.productId)) {
        this.onLoad();
      }
    }
  },
  methods: {
    init() {
      getDetail(this.productId).then(res => {
        this.detail = res.data.data;
      });
    },
    snapshotOperation() {
      this.$refs.tree.option.addBtn = false;
      this.$refs.crud.option.editBtn = false;
      this.$refs.crud.option.delBtn = false;
      this.$refs.crud.option.viewBtn = true;
    },
    viewDraft() {
      this.$router.push({
        path: `/iot/product/draft/${this.productKey}/${this.productId}`,
      });
    },
    nodeClickTree(data) {
      this.activeName = data.isDefault === 1 ? "默认模块" : data.title;
      this.blockId = data.key;
      this.data = this.functionSnapshot.filter(item => item.blockId === data.key);
    },
    filterNodeMethod(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    transForm(row) {
      // 功能类型
      const functionType = this.form?.functionType;
      if (functionType === 2) {
        // 输入参数
        this.inputData = row.specInput;
        // 输出参数
        this.outputData = row.specOutput;
      }
      if (functionType === 3) {
        // 输出参数
        this.outputData = row.specOutput;
      }
      // 属性功能
      if (functionType === 1) {
        if (row.specFunction.fieldType === "enum") {
          // 枚举数据
          this.enumsData = func.keyValueToJsonArray(row.specFunction.specEnum);
        }
        if (row.specFunction.fieldType === "struct") {
          // 属性结构体
          this.structData = row.specFunction.specStruct;
        }
        row.specFunctionId = row.specFunction.id; // 功能主键
        row.fieldType = row.specFunction.fieldType; // 数据类型
        row.specMin = row.specFunction.specMin; // 最小值
        row.specMax = row.specFunction.specMax; // 最大值
        row.specStep = row.specFunction.specStep; // 步长
        row.specUnit = row.specFunction.specUnit; // 单位
        row.specEnum = row.specFunction.specEnum; // 枚举数据
        row.specBoolFalse = row.specFunction.specBoolFalse; // 布尔值 0
        row.specBoolTrue = row.specFunction.specBoolTrue; // 布尔值 1
        row.specLength = row.specFunction.specLength; // 数据长度
        row.specDateFormat = row.specFunction.specDateFormat; // 时间格式
        row.specItemType = row.specFunction.specItemType; // 元素类型
        row.specSize = row.specFunction.specSize; // 元素个数

      }
      return row;
    },
    beforeOpen(done, type) {
      if (["view"].includes(type)) {
        const data = this.functionSnapshot.find(item => item.id === this.form.id);
        this.form = this.transForm(data);
        if (data.functionType === 1) {
          this.form.fieldType = data.specFunction.fieldType;
          this.form.specFunctionId = data.specFunction.id;
        }
      }
      done();
    },
    beforeClose(done) {
      this.form = {};
      this.structData = [];
      this.enumsData = [];
      this.inputData = [];
      this.outputData = [];
      done();
    },
    openTsl() {
      // 设置物模型
      if (!validatenull(this.productId) && !validatenull(this.blockId)) {
        dataPublishedTsl(this.productId, this.blockId).then(res => {
          this.tsl = JSON.stringify(res.data.data);
        });
      }
      this.visibleTsl = true;
    },
    exportTsl() {
      this.$confirm('是否导出物模型？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        exportBlob(
          `/blade-iot/product/version/tsl-export?productKey=${this.productKey}`
        ).then(res => {
          downloadJson(res.data, `product_tsl_${this.detail.productName}_${this.productKey}_v${this.dataSnapshot.profile.versionNo}.json`);
        });
      });
    },
    beforeCloseTsl() {
      this.tsl = "";
      this.visibleTsl = false;
    },
    blockTslChange(value) {
      if (!validatenull(value)) {
        this.blockId = value;
      }
      dataPublishedTsl(this.productId, this.blockId).then(res => {
        this.tsl = JSON.stringify(res.data.data);
      });
    },
    onLoad() {
      dataPublishedByKey(this.productKey).then(res => {
        this.dataSnapshot = res.data.data;
        if (validatenull(this.dataSnapshot.profile)) {
          return;
        }
        this.versionTip = `v${this.dataSnapshot.profile.versionNo} (${this.dataSnapshot.profile.versionDate})`;
        // 将三个列表合并返回，并且根据默认的blockId筛选出对应的列表
        // 树形点击的时候判断versionId是否为空，如果为空则调用接口，否则就循环snapshot的值
        // 选中版本后，给versionId设置值。恢复版本或者返回版本后给versionId设置空
        const properties = this.dataSnapshot.properties
        const commands = this.dataSnapshot.commands;
        const events = this.dataSnapshot.events;
        // 设置功能列表快照
        this.functionSnapshot = [...properties, ...commands, ...events].map(item => {
          return {
            ...item,
            fieldTypeName: fieldTypeName(item),
            dataTypeName: dataTypeName(item)
          }
        });
        // 循环snapshot的值，将blockName改成title，id改成value然后返回
        const blockSnapshot = this.dataSnapshot.blocks.map(item => {
          return {
            id: item.id,
            key: item.id,
            value: item.id,
            title: item.blockName,
            tag: item.tag,
            isDefault: item.isDefault
          }
        });
        this.blockSnapshot = blockSnapshot;
        this.dataTree = blockSnapshot;
        // 选中默认的模块
        let defaultItem = this.dataTree.find(item => item.isDefault === 1);
        if (!validatenull(defaultItem)) {
          this.$refs.tree.setCurrentKey(defaultItem.key);
          this.blockId = defaultItem.key;
          this.data = this.functionSnapshot.filter(item => item.blockId === defaultItem.key);
        }
        // 设置物模型
        if (!validatenull(this.productId) && !validatenull(this.blockId)) {
          dataPublishedTsl(this.productId, this.blockId).then(res => {
            this.tsl = JSON.stringify(res.data.data);
          });
        }
      });
    },
  }
};
</script>

<style>
.el-row {
  margin-bottom: 20px;
}

.el-row:last-child {
  margin-bottom: 0;
}

.cursor {
  cursor: pointer;
}
</style>
